Ext.grid.PropertyColumnModel = Ext.extend(Ext.grid.ColumnModel, {
	// private - strings used for locale support
	nameText : '属性名称',
	valueText : '属性值',
	dateFormat : 'm/j/Y',
	trueText : '是',
	falseText : '否',

	constructor : function(grid, store) {
		var g = Ext.grid, f = Ext.form;

		this.grid = grid;
		g.PropertyColumnModel.superclass.constructor.call(this, [{
			header : this.nameText,
			width : 50,
			sortable : true,
			dataIndex : 'name',
			id : 'name',
			menuDisabled : true
		}, {
			header : this.valueText,
			width : 50,
			resizable : false,
			dataIndex : 'value',
			id : 'value',
			menuDisabled : true
		}, {
			header : 'group',
			dataIndex : 'group',
			hidden : true
		}]);
		this.store = store;

		var bfield = new f.Field({
			autoCreate : {
				tag : 'select',
				children : [{
					tag : 'option',
					value : 1,
					html : this.trueText
				}, {
					tag : 'option',
					value : 0,
					html : this.falseText
				}]
			},
			getValue : function() {
				return this.el.dom.value;
			}
		});
		this.editors = {
			'date' : new g.GridEditor(new f.DateField({
				selectOnFocus : true
			})),
			'string' : new g.GridEditor(new f.TextField({
				selectOnFocus : true
			})),
			'number' : new g.GridEditor(new f.NumberField({
				selectOnFocus : true,
				style : 'text-align:left;'
			})),
			'boolean' : new g.GridEditor(bfield, {
				autoSize : 'both'
			})
		};
		this.renderCellDelegate = this.renderCell
				.createDelegate(this);
		this.renderPropDelegate = this.renderProp
				.createDelegate(this);
	},

	// private
	renderDate : function(dateVal) {
		return dateVal.dateFormat(this.dateFormat);
	},

	// private
	renderBool : function(bVal) {
		return this[bVal ? 'trueText' : 'falseText'];
	},

	// private
	isCellEditable : function(colIndex, rowIndex) {
		var p = this.store.getAt(rowIndex)
		return colIndex == 1 && p.data.editable !== false;
	},

	// private
	getRenderer : function(col) {
		return col == 1
				? this.renderCellDelegate
				: this.renderPropDelegate;
	},

	// private
	renderProp : function(v) {
		return this.getPropertyName(v);
	},

	// private
	renderCell : function(val, meta, rec) {
		var renderer = this.grid.customRenderers[rec
				.get('column')];
		if (renderer) {
			return renderer.apply(this, arguments);
		}
		var type = rec.data.type;
		var rv = val;
		if (type == 'date') {
			rv = this.renderDate(val);
		} else if (type == 'boolean') {
			rv = this.renderBool(val);
		} 
		return Ext.util.Format.htmlEncode(rv);
	},

	// private
	getPropertyName : function(name) {
		var pn = this.grid.propertyNames;
		return pn && pn[name] ? pn[name] : name;
	},

	// private
	getCellEditor : function(colIndex, rowIndex) {
		var p = this.store.getAt(rowIndex), n = p.data.column, type = p.data.type;
		
		if (this.grid.customEditors[n]) {
			return this.grid.customEditors[n];
		}
		
		if (type == 'boolean') {
			return this.editors['boolean'];
		} else if (type == 'number') {
			return this.editors.number;
		} else if (type == 'boolean') {
			return this.editors['boolean'];
		} else {
			return this.editors.string;
		}
			
		/*
		if (Ext.isDate(val)) {
			return this.editors.date;
		} else {
			return this.editors.string;
		}
		*/
	},

	// inherit docs
	destroy : function() {
		Ext.grid.PropertyColumnModel.superclass.destroy
				.call(this);
		this.destroyEditors(this.editors);
		this.destroyEditors(this.grid.customEditors);
	},

	destroyEditors : function(editors) {
		for ( var ed in editors) {
			Ext.destroy(editors[ed]);
		}
	}
});

Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {
	enableColumnMove : false,
	stripeRows : false,
	trackMouseOver : false,
	clicksToEdit : 1,
	enableHdMenu : false,
	viewConfig : {
		forceFit : true
	},
	view : new Ext.grid.GroupingView({
		showGroupName : false,
		forceFit : true,
		groupTextTpl : '{text}'
	}),
	tbar : [{
		iconCls : 'icon_group_expand'
	}, {
		iconCls : 'icon_group_expand'
	}],
	// private
	initComponent : function() {
		this.customRenderers = this.customRenderers || {};
		this.customEditors = this.customEditors || {};
		this.lastEditRow = null;
		this.ds = this.store;
		this.cm = new Ext.grid.PropertyColumnModel(this, this.store);
		Ext.grid.PropertyGrid.superclass.initComponent.call(this);

		this.mon(this.selModel, 'beforecellselect', function(sm, rowIndex, colIndex) {
			if (colIndex === 0) {
				this.startEditing.defer(200, this, [rowIndex, 1]);
				return false;
			}
		}, this);
	},

	// private
	onRender : function() {
		Ext.grid.PropertyGrid.superclass.onRender.apply(this, arguments);

		this.getGridEl().addClass('x-props-grid');
	},

	// private
	afterRender : function() {
		Ext.grid.PropertyGrid.superclass.afterRender.apply(this, arguments);
		if (this.source) {
			this.setSource(this.source);
		}
	},
	
	setSource : function(source) {
		this.store.removeAll();
		var o = source;

		var data = [];
		for ( var i = 0; i < o.length; i++) {
			var oi = o[i];
			data.push(new this.store.recordType(oi,
					oi.column));
		}
		this.store.loadRecords({
			records : data
		}, {}, true);
	},

	removeProperty : function(prop) {
		this.store.remove(prop);
	}

});

Ext.reg("propertygrid", Ext.grid.PropertyGrid);
